package org.onejava.core.manage;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.onejava.core.annotation.ActionInfo;
import org.onejava.core.bean.ActionEntity;
import org.onejava.core.bean.Allconfig;
import org.onejava.core.bean.InterceptorEntity;
import org.onejava.core.bean.MContext;
import org.onejava.core.exception.MMException;
import org.onejava.core.manage.inter.ActionManage;
import org.onejava.core.tools.ObjectTools;
import org.onejava.core.tools.ScanTool;


/**
 * Action管理类
 * @author frost
 *
 */
public class KActionManage extends BaseManage implements ActionManage {
	private static ActionManage am;
	private HashMap<String,ActionEntity> actionMap;
    private   Log log = LogFactory.getLog(KActionManage.class);  

	/**
	 * 禁止实例化
	 */
	private KActionManage(){}
	
	/**
	 * 获取Action管理类的单例
	 * @return ActionManage
	 */
	public static ActionManage getActionManage(){
		if(null==am){
			return am=new KActionManage();
		}
		return am;
	}
	/**
	 * 初始化ActionMap
	 * @param packagePath Action根目录
	 * @throws Exception 
	 */
	public void initActionMap(String packagePath) throws Exception {
		if(null!=actionMap){
			return;
		}
		//扫描出所有Action路径
		ScanTool sacntool = new ScanTool();
		List<String> list = sacntool.getAllClassName(Allconfig.truePath,packagePath);
		//根据ActionName加载<前置拦截器链><后置拦截器链>进入ActionContext
		actionMap = new HashMap<String, ActionEntity>(100);
		for(int i=0;i<list.size();i++){
			Object actionObj = ObjectTools.getTheObject(list.get(i));
			Method method=null;
			log.info("开始在加载<"+list.get(i)+">");
			try {
				method = ObjectTools.getMethod(actionObj, Allconfig.defaultMethod, MContext.class);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				log.warn("扫描到的类<"+list.get(i)+">没有有效的<"+Allconfig.defaultMethod+">方法");
				continue;
			}
			Map actionInfoMap = getActionInfo(method,list.get(i));
			String before = (String) actionInfoMap.get("befores");
			String after = (String) actionInfoMap.get("afters");
			String befores[] = before.split(",");
			String afters[] = after.split(",");
			InterceptorManage im = InterceptorManage.getManage();
			//获取前置拦截器链
			InterceptorEntity[] beforeInterceptors = im.getInterceptorChain(befores);
			//获取后置拦截器链
			InterceptorEntity[] afterInterceptors = im.getInterceptorChain(afters);
			ActionEntity ac = new ActionEntity("",actionObj,method,beforeInterceptors,afterInterceptors);
			//使用Ioc插件注入变量
			setBean(ac);
			setService(ac);
			String path = list.get(i).toLowerCase();
			actionMap.put(path, ac);
			log.info(path+":加载完成");		
		}
	}
	public void reloadAction(String actionName){
		
	} 
	/**
	 * 执行Action
	 * @param actionName
	 * @param method
	 * @throws Exception 
	 */
	public Object doAction(String actionName,String method,MContext context) throws Exception{
		//获取Action的对象和方法
		ActionEntity ac = actionMap.get(actionName);
		//Object obj = ac.getObj();
		//Method md = ac.getMethod();
		Object result=null;
		try {
			result=ObjectTools.invokeObject(ac.getObj(), ac.getMethod(), context);
		}catch (InvocationTargetException e) {
			// TODO Auto-generated catch block	
			//log.error("发生了错误", e.getTargetException());
			throw new Exception(e.getTargetException());
		} 
		return result;
	}
	
	/**
	 * 获取后置拦截器链
	 * @param actionName
	 * @param method
	 * @return
	 */
	public InterceptorEntity[] getAfterInterceptorChain(String classpath){
		return actionMap.get(classpath).getAfterInterceptors();	
	}
	/**
	 * 获取前置拦截器链
	 * @param actionName
	 * @param method
	 * @return
	 */
	public InterceptorEntity[] getBeforeInterceptorChain(String classpath){
		return actionMap.get(classpath).getBeforeInterceptors();	
	}
	
	/**
	 * 判断路径是否有对应的Action
	 * @return
	 */
	public boolean actionIsExeit(String classPath){
		if(null==actionMap){
			return false;
		}
		return 	actionMap.containsKey(classPath);
	} 
	
	/**
	 * 获取Action的注解信息
	 * @param msa
	 * @return Map{befores，afters}
	 */
	private Map getActionInfo(Method msa,String path){
		path=path.trim();
		int a = path.lastIndexOf(".");
		path = path.substring(0,a);
        Package pkg = Package.getPackage(path);
        String pageBefores="";
        String pageAfters="";
        if(null!=pkg){
        	 ActionInfo pageAnnotation=pkg.getAnnotation(ActionInfo.class);
        	 if(null!=pageAnnotation){
        		 pageBefores = pageAnnotation.before();
        		 pageAfters = pageAnnotation.after();
        	 }
        }
        
		ActionInfo annotation = msa.getAnnotation(ActionInfo.class);
		Map<String, String> map  = new HashMap<String, String>(2);
		if(null!=annotation){
			String befores = annotation.before();
			String afters = annotation.after();
			if("".equals(pageBefores)){
				map.put("befores",befores);
			}else{
				map.put("befores", pageBefores+","+befores);
			}
			if("".equals(afters)){
				map.put("afters", afters);
			}else{
				map.put("afters", afters+","+pageAfters);
			}
			
		}else{
			map.put("befores", "");
			map.put("afters", "");
		}

		return map;
		
	} 
	
	
	
}
